home *** CD-ROM | disk | FTP | other *** search
- ; $Id: d_globe.pro,v 1.19 1997/04/18 17:51:14 alan Exp $
- ;
- ; Copyright (c) 1997, Research Systems, Inc. All rights reserved.
- ; Unauthorized reproduction prohibited.
- ;
- ;+
- ; FILE:
- ; d_globe.pro
- ;
- ; CALLING SEQUENCE: d_globe
- ;
- ; PURPOSE:
- ; Demonstrates texture mapping, model rotations, and indexed color
- ; table stretching with IDL's object graphics system.
- ; (object graphics only)
- ;
- ; MAJOR TOPICS: Indexed colors & Color palettes, Texture Mapping, Trackball.
- ;
- ; CATEGORY:
- ; IDL 5.0
- ;
- ; INTERNAL FUNCTIONS and PROCEDURES:
- ; pro globergbstretch - stretches RGB vectors into new RGB vectors
- ; pro globestretch_event - event handler for stretching colors
- ; pro d_globe_event - event handler
- ; pro d_globecleanup - cleanup routine
- ; pro globereadimages - inputs and scales images
- ; function globemakeobjects - creates the object hierarchy
- ; pro d_globe - Main procedure
- ;
- ; EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
- ; pro trackball__define.pro - Create trackball object.
- ; pro orb__define.pro - Create an orb object
- ; pro gettips - Get the tips text structure..
- ; pro widtips - Create the widget text for tips.
- ; globe.txt - "About" file
- ; globe.tip - "Tips" file
- ; worldelv.dat - global topography image dataset
- ; worldtmp.sav - global temperature image dataset & RGB's
- ;
- ; REFERENCE: IDL Reference Guide, IDL User's Guide
- ;
- ;
- ; NAMED STRUCTURES:
- ; none.
- ;
- ; COMMON BLOCS:
- ; none.
- ;
- ; MODIFICATION HISTORY: Written by: MCR, RSI, February 97
- ;-
- ;----------------------------------------------------------------------
- ; PURPOSE This routine stretches old RGB vectors
- ; (oldReds, oldGreens, oldBlues) based on
- ; low and high stretch values (low, high)
- ; and passes back new RGB vectors
- ; (newReds, newGreens, newBlues). This routine
- ; is based on the Stretch.pro routine found within
- ; the IDL distribution. One may stretch color vectors
- ; of any length.
- ;
- pro GlobeRGBStretch, $
- oldReds, oldGreens, oldBlues, $ ;IN: Input RGB Vectors
- newReds, newGreens, newBlues, $ ;OUT: Output RGB Vectors
- LOW=low, HIGH=high ;IN: (opt) stretch indices
-
- WIDGET_CONTROL, HOURGLASS = 1
-
- nColors=N_ELEMENTS(oldReds)
-
- if (not KEYWORD_SET(low)) then $
- low=0L
-
- if (not KEYWORD_SET(high)) then $
- high=nColors-1L
-
- if (high-low ne 0) then begin ;if low and high are not equal
- slope=FLOAT(nColors-1)/(high-low)
- intercept=-slope*low
- endif else begin ;if low and high are equal
- slope=0b & intercept=low
- endelse
-
- sub=LONG(FINDGEN(nColors)*slope+intercept)
- newReds=oldReds[sub]
- newGreens=oldGreens[sub]
- newBlues=oldBlues[sub]
- WIDGET_CONTROL, HOURGLASS = 0
-
- end
-
- ;----------------------------------------------------------------------
- ;
- ; PURPOSE ; This is a secondary event handler routine
- ; used in the Globe demo. This routine is used
- ; to stretch the coor indices of the respective
- ; datasets. One can either stretch the color vectors
- ; for the temperature data or stretch the colors
- ; vectors for the topography data.
- ;
- pro GlobeStretch_Event, $
- sEvent
-
- WIDGET_CONTROL, HOURGLASS = 1
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- WIDGET_CONTROL, sEvent.id, GET_UVALUE=wsliders
-
- ; Build subscripts of RGB vectors associated
- ; with the images.
- ;
- elev=LINDGEN(sState.nColors/2)
- temps=LINDGEN(sState.nColors/2)+sState.nColors/2
-
- ; Check that minimim sliders do not exceed
- ; the maximum sliders and
- ; that maximum sliders are not less than minimum sliders
- ; and make adjustments as needed.
- ;
- WIDGET_CONTROL, wsliders[0], GET_VALUE=sliderValue0
- WIDGET_CONTROL, wsliders[1], GET_VALUE=sliderValue1
- WIDGET_CONTROL, wsliders[2], GET_VALUE=sliderValue2
- WIDGET_CONTROL, wsliders[3], GET_VALUE=sliderValue3
-
- if (sEvent.id EQ wsliders[0] and sliderValue0 gt sliderValue1) then begin
- WIDGET_CONTROL, wsliders[0], SET_VALUE=sliderValue1
- sliderValue0 = sliderValue1
- endif
-
- if (sEvent.id EQ wsliders[1] and sliderValue0 gt sliderValue1) then begin
- WIDGET_CONTROL, wsliders[1], SET_VALUE=sliderValue0
- slidervalue1 = sliderValue0
- endif
-
- if (sEvent.id EQ wsliders[2] and sliderValue2 gt sliderValue3) then begin
- WIDGET_CONTROL, wsliders[2], SET_VALUE=sliderValue3
- sliderValue2 = sliderValue3
- endif
-
- if (sEvent.id EQ wsliders[3] and sliderValue2 gt sliderValue3) then begin
- WIDGET_CONTROL, wsliders[3], SET_VALUE=sliderValue2
- sliderValue3 = sliderValue2
- endif
-
- ; Stretch the original color vectors and then save the stretched
- ; vectors into the color palette. Note, the original colors are
- ; always stretch so that information is not lost by stretching
- ; vectors that have already been stretched.
- ; (both datasets individually)
- ;
- GlobeRGBStretch, sState.reds[elev], sState.greens[elev], $
- sState.blues[elev], newReds1, newGreens1, newBlues1, $
- LOW=sliderValue0, HIGH=sliderValue1
-
- GlobeRGBStretch, sState.reds[temps], sState.greens[temps], $
- sState.blues[temps], newReds2, newGreens2, newBlues2, $
- LOW=sliderValue2-sState.ncolors/2, $
- HIGH=sliderValue3-sState.ncolors/2
-
- reds=[newReds1, newReds2]
- greens=[newGreens1, newGreens2]
- blues=[newBlues1, newBlues2]
-
- sState.oPalette->SetProperty, RED_VALUES=reds, $
- GREEN_VALUES=greens, BLUE_VALUES=blues
-
- sState.oWindow->Draw, sState.oView
-
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- WIDGET_CONTROL, HOURGLASS = 0
-
- end
-
- ;----------------------------------------------------------------------
- ;
- ; PURPOSE This is the main event handler routine
- ; use in the Globe demo.
- ;
- pro d_Globe_Event, $
- sEvent
-
- ; Quit this application using the close box.
- ;
- if (TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ $
- 'WIDGET_KILL_REQUEST') then begin
- WIDGET_CONTROL, sEvent.top, /DESTROY
- RETURN
- endif
-
- WIDGET_CONTROL, sEvent.id, GET_UVALUE=uvalue
- case uvalue of
-
- ; Handle radio button events .
- ; Here Handle event for showing over continents.
- ;
- 'RADIO1': begin
- WIDGET_CONTROL, HOURGLASS=1
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- WIDGET_CONTROL, sState.wGroup2, GET_VALUE=twin
- if (sEvent.value EQ 0 AND twin EQ 0) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTemp
- if (sEvent.value EQ 1 AND twin EQ 0) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTopoTemp
- if (sEvent.value EQ 1 AND twin EQ 1) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTopo
- if (sEvent.value EQ 0 AND twin EQ 1) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTempTopo
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, HOURGLASS=0
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- end
-
- ; Reset perspective.
- ;
- 'RESET': begin
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oModelRotate->SetProperty, $
- TRANSFORM=sState.resetTransform
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- end
-
- ; Handle radio button events.
- ; Here Handle event for showing over oceans.
- ;
- 'RADIO2': begin
- WIDGET_CONTROL, HOURGLASS=1
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- WIDGET_CONTROL, sState.wGroup1, GET_VALUE=twin
- if (sEvent.value EQ 0 AND twin EQ 0) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTemp
- if (sEvent.value EQ 1 AND twin EQ 0) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTempTopo
- if (sEvent.value EQ 1 AND twin EQ 1) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTopo
- if (sEvent.value EQ 0 AND twin EQ 1) then $
- sState.oImage->SetProperty, DATA=*sState.pImageTopoTemp
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, HOURGLASS=0
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- end
-
- ; Handle trackball events here.
- ; still need to add trackball object
- ; and place in object hierarchy.
- ;
- 'DRAW': begin
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- bHaveTransform=sState.oTrack->Update(sEvent, TRANSFORM=qmat)
- if (bHaveTransform NE 0) then begin
- sState.oModelRotate->GetProperty, TRANSFORM=trans
- mtrans=trans # qmat
- sState.oModelRotate->SetProperty, TRANSFORM=mtrans
- endif
-
- ; Handle button press.
- ;
- if (sEvent.type EQ 0) then $
- WIDGET_CONTROL, sState.wDraw, DRAW_MOTION=1
- if (sEvent.type EQ 2) then begin
- if (bHaveTransform) then begin
- sState.oWindow->SetProperty, QUALITY=0
- sState.oWindow->Draw,sState.oView
- endif
- endif
-
- ; Handle button release.
- ;
- if (sEvent.type EQ 1) then begin
- sState.oWindow->SetProperty, QUALITY=2
- WIDGET_CONTROL, sState.wDraw, DRAW_MOTION=0
- sState.oWindow->Draw, sState.oView
- endif
-
- ; Handle expose events.
- ;
- if (sEvent.type EQ 4) then begin
- sState.oWindow->Draw, sState.oView
- endif
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- end
-
- ; Quit this application.
- ;
- 'QUIT': begin
- WIDGET_CONTROL, sEvent.top, /DESTROY
- end
-
- ; Display the information file.
- ;
- 'ABOUT' : begin
- if (XREGISTERED('XDisplayFile') NE 0) then RETURN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- XDISPLAYFILE, sState.fileNameAbout, $
- WIDTH=55, HEIGHT=14, DONE_BUTTON='Done', $
- TITLE='About the Globe Demo' , $
- GROUP=sEvent.top
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- end
-
- ; Handle all other events.
- ;
- ELSE: ; Do nothing
-
- endcase
-
- end
-
- ;----------------------------------------------------------------------
- ;
- ; PURPOSE Cleanup everything associated with the
- ; Globe demo, including all objects and pointers.
- ; Restore the original color table.
- ;
- pro d_GlobeCleanup, tlb
-
- WIDGET_CONTROL, tlb, GET_UVALUE=sState, /NO_COPY
-
- ; Restore the previous color table.
- ;
- TVLCT, sState.colorTable
-
- ; Destroy the top objects & attribute objects.
- ;
- OBJ_DESTROY, sState.oView
- OBJ_DESTROY, sState.oPalette
- OBJ_DESTROY, sState.oTrack
- OBJ_DESTROY, sState.oText
- OBJ_DESTROY, sState.oFont
- OBJ_DESTROY, sState.oContainer
-
- ; Free all pointers.
- ;
- PTR_FREE, sState.pImageTempTopo
- PTR_FREE, sState.pImageTopoTemp
- PTR_FREE, sState.pImageTemp
- PTR_FREE, sState.pImageTopo
-
- ; Map the group leader base if it exists.
- ;
- if (WIDGET_INFO(sState.groupBase, /VALID_ID)) then $
- WIDGET_CONTROL, sState.groupBase, /MAP
-
- end
-
- ;----------------------------------------------------------------------
- ;
- ; PURPOSE Inputs the images used in the Globe demo.
- ; This procedure returns
- ; four pointers back to the caller.
- ; These pointers point to the given images.
- ;
- pro GlobeReadImages, $
- fileNameElev, $ ;IN: filename for elevation dataset
- fileNameTemp, $ ;IN: filename for temperature dataset
- nColors, $ ;IN: number of colors used to scale both images
- pImageTemp, $ ;OUT: world temperatures
- pImageTopo, $ ;OUT: world topography
- pImageTempTopo, $ ;OUT: continental temperature and oceanic elevation
- pImageTopoTemp, $ ;OUT: ocean temperature and continental elevation
- reds, $ ;OUT: red color indices
- greens, $ ;OUT: green color indices
- blues ;OUT: blue color indices
-
- ; Innput DEM from IDL distribution ("worldelv.dat") and
- ; corresponding temperature dataset from
- ; a .SAV file ("worldtmp.sav").
- ;
- OPENR, lun, fileNameElev, /GET_LUN
- topo=BYTARR(360, 360)
- READU, lun, topo
- CLOSE, LUN
- FREE_LUN, lun
- temps=BYTARR(360, 360)
-
- ; Read the temperature image.
- ;
- Read_Gif, fileNameTemp, Temps, Reds, Greens, Blues
-
- ; Build masks to divide the two datasets.
- ;
- oceanMask=WHERE(topo lt 124)
- landMask=WHERE(topo ge 124)
-
- ; Create DEM( Digital elevation Model) images.
- ; (Color Ranges: [0]-[nColors/2-1]).
- ;
- topoOceanScaled=BYTSCL(topo, TOP=nColors/2-1, $
- MIN=MIN(topo[oceanMask]), MAX=MAX(topo[oceanMask]))
- topoLandScaled=BYTSCL(topo, TOP=nColors/2-1, $
- MIN=MIN(topo[landMask]), MAX=MAX(topo[landMask]))
- topoScaled=BYTSCL(topo, TOP=nColors/2-1)
-
- ; Create temperature images.
- ; (Color Ranges: [nColors/2]-[nColors-1]).
- ;
- tempLandScaled=BYTSCL(temps, TOP=nColors/2-1, $
- MIN=MIN(temps[landMask]), $
- MAX=MAX(temps[landMask]))+BYTE(nColors/2)
- tempOceanScaled=BYTSCL(temps, TOP=nColors/2-1, $
- MIN=MIN(temps[oceanMask]), $
- MAX=MAX(temps[oceanMask]))+BYTE(nColors/2)
- tempScaled=BYTSCL(temps, TOP=nColors/2-1)+BYTE(nColors/2)
-
- ; Create pointers to two images that are created based on the
- ; respective topography and temperature scalings.
- ;
- pImageTemp=PTR_NEW(tempScaled)
- pImageTopo=PTR_NEW(topoScaled)
- imageTempTopo=BYTARR(360, 360) ;temperatures over continents
- imageTempTopo[landMask]=tempLandScaled[landMask]
- imageTempTopo[oceanMask]=topoOceanScaled[oceanMask]
- pImageTempTopo=PTR_NEW(imageTempTopo)
- imageTopoTemp=BYTARR(360, 360) ;temperatures over oceans
- imageTopoTemp[oceanMask]=tempOceanScaled[oceanMask]
- imageTopoTemp[landMask]=topoLandScaled[landMask]
- pImageTopoTemp=PTR_NEW(imageTopoTemp)
-
- ; Scale color vectors based on number of colors.
- ;
- reds=CONGRID(reds, nColors)
- greens=CONGRID(greens, nColors)
- blues=CONGRID(blues, nColors)
-
- end
-
- ;----------------------------------------------------------------------
- ;
- ; PURPOSE Creates the object hierarchy
- ;
- function GlobeMakeObjects, $
- reds, $ ;IN: red color lookups
- greens, $ ;IN: green color lookups
- blues, $ ;IN: blue color lookups
- screenSize, $ ;IN: screensize dimensions
- pImageTempTopo, $ ;IN: pointer to image
- oWindow ;IN: window object
-
- myView = [-1.0, -1.0, 2.0, 2.0]
- ; Create view object.
- ;
- oView = OBJ_NEW('IDLgrView', PROJECTION=2, EYE=4.0, $
- COLOR=[0,0,0], $
- VIEW=[-1.0, -1.0, 2.0, 2.0], ZCLIP=[1.0, -1.0])
-
- ; Make the starting up text location centered.
- ;
- textLocation = [myview[0]+0.5*myview[2], myview[1]+0.5*myview[3]]
-
- ; Create and display the PLEASE WAIT text.
- ;
- oFont = OBJ_NEW('IDLgrFont', 'Helvetica', SIZE=20)
- oText = OBJ_NEW('IDLgrText', $
- 'Starting up Please wait...', $
- ALIGN=0.5, $
- LOCATION=textLocation, $
- COLOR=[255,255,0], FONT=oFont)
-
-
- ; Create model objects for translation, rotation, and scaling.
- ;
- oModelTranslate=OBJ_NEW('IDLgrModel')
- oModelRotate=OBJ_NEW('IDLgrModel')
- oModelScale=OBJ_NEW('IDLgrModel')
- oModelTranslate->Add, oModelRotate
- oModelRotate->Add, oModelScale
-
- ; Show the starting up text.
- ;
- oview->Add, oModelTranslate
- oModelTranslate->Add, oText
- owindow->Draw, oView
-
- ; Create color palette object.
- ;
- oPalette=obj_new('IDLgrPalette', reds, greens, blues)
-
- ; Create trackball object.
- ;
- oTrack=OBJ_NEW('trackball', $
- [(screenSize[0]*.4)/2.0, (screenSize[0]*.4)/2.0], $
- (screenSize[0]*.4)/2.0)
-
- ; Create image object and add to model hierarchy.
- ;
- oImage=OBJ_NEW('IDLgrImage', *pImageTempTopo, HIDE=1, $
- PALETTE=oPalette)
- oModelRotate->Add, oImage
-
- ; Create orb object and add to model hierarchy.
- ;
- oSphere=OBJ_NEW('orb', DENSITY=0.99, /TEX_COORDS, $
- TEXTURE_MAP=oImage, COLOR=[255, 255, 255], RADIUS=0.90)
- oModelRotate->Add, oSphere
-
- ; Add model hierarchy to view, rotate or whatever,
- ; draw view to window.
- ;
- oModelRotate->Rotate, [1, 0, 0], -90
-
- oModelRotate->GetProperty, TRANSFORM=resetTransform
-
- oContainer = OBJ_NEW('IDLgrContainer')
- oContainer->Add, oView
- oContainer->Add, oTrack
-
- RETURN, {oView:oView, $
- oModelTranslate: oModelTranslate, $
- oModelRotate: oModelRotate, $
- oModelScale: oModelScale, $
- oPalette: oPalette, $
- oImage: oImage, $
- oSphere: oSphere, $
- oTrack: oTrack, $
- oWindow: oWindow, $
- oContainer: oContainer, $
- OText: oText, $
- OFont: oFont, $
- resetTransform:resetTransform}
-
- end
-
- ;----------------------------------------------------------------------
- ;
- ; PURPOSE This is the main widget definition
- ; routine used in the Globe demo.
- ; It constructs a widget and object
- ; hierarchy which can be used to
- ; manipulate some images.
- ;
- pro D_Globe, $
- GROUP=group, $ ;IN: (opt) group identifier
- APPTLB=apptlb ;OUT: (opt) TLB of this application
-
- ; Check the validity of the group identifier.
- ;
- ngroup=N_ELEMENTS(group)
- if (ngroup NE 0) then begin
- check=WIDGET_INFO(group, /VALID_ID)
- if (check NE 1) then begin
- print,'Error, the group identifier is not valid'
- print, 'Return to the main application'
- RETURN
- endif
- groupBase = group
- endif else groupBase = 0L
-
- ; Get the current color table.
- ; It will be restored when exiting.
- ;
- TVLCT, savedR, savedG, savedB, /GET
- colorTable=[[savedR],[savedG],[savedB]]
-
- ; Get the screen size.
- ;
- DEVICE, GET_SCREEN_SIZE = screenSize
-
- ; Declare filenames used with the globe demo.
- ;
- fileNameElev=FILEPATH('worldelv.dat', $
- SUBDIR=['examples','data'])
- fileNameTemp=FILEPATH('worldtmp.gif', $
- SUBDIR=['examples','demo','demodata'])
- fileNameTips=FILEPATH('globe.tip', $
- SUBDIR=['examples','demo','demotext'])
- fileNameAbout=FILEPATH('globe.txt', $
- SUBDIR=['examples','demo','demotext'])
-
- ; Get the tips.
- ;
- sText=getTips(fileNameTips)
- nWidgets=2
- wText=LONARR(nWidgets)
-
- ; Read image datasets. GlobeReadImages returns two pointers to the
- ; respective images. Each image contains two datasets, whereby
- ; each dataset is scaled using half of the colors specified
- ; in calling GlobeReadImages.
- ;
- nColors=190
- GlobeReadImages, fileNameElev, fileNameTemp, nColors, $
- pImageTemp, pImageTopo, pImageTempTopo, pImageTopoTemp, $
- reds, greens, blues
-
- ; Construct all base widgets.
- ;
- if (N_ELEMENTS(group) EQ 0) then begin
- wTopBase=WIDGET_BASE(TITLE='Globe Demo', $
- XPAD=0, YPAD=0, $
- /TLB_KILL_REQUEST_EVENTS, $
- /COLUMN, TLB_FRAME_ATTR=1, MBAR=barBase)
- endif else begin
- wTopBase=WIDGET_BASE(TITLE='Globe Demo', $
- XPAD=0, YPAD=0, $
- /TLB_KILL_REQUEST_EVENTS, $
- GROUP_LEADER=group, $
- /COLUMN, TLB_FRAME_ATTR=1, MBAR=barBase)
- endelse
-
- ; Create the buttons in the menu bar.
- ;
- wFileButton=WIDGET_BUTTON(barBase, VALUE='File')
-
- wQuitButton=WIDGET_BUTTON(wFileButton, VALUE='Quit', $
- UVALUE='QUIT')
-
- wOptionButton=WIDGET_BUTTON(barBase, VALUE='Options')
-
- wResetButton=WIDGET_BUTTON(wOptionButton, $
- VALUE='Reset Orientation', UVALUE='RESET')
-
- wHelpButton=WIDGET_BUTTON(barBase, VALUE='About', /HELP)
-
- wAboutButton=WIDGET_BUTTON(wHelpButton, UVALUE='ABOUT', $
- VALUE='About the Globe Demo')
-
- ; Create the widgets other than the menu bar.
- ;
- wSubBase=WIDGET_BASE(wTopBase, COLUMN=2)
-
- wLeftBase=WIDGET_BASE(wSubBase, /ALIGN_CENTER, /COLUMN)
-
- wLeftBaseSub1=WIDGET_BASE(wLeftBase, $
- /ALIGN_CENTER, /COLUMN, /FRAME)
-
- wSelect1=WIDGET_LABEL(wLeftBaseSub1, $
- VALUE='Display Over Continents:')
-
- radioOptions=['Temperature', 'Topography']
-
- wGroup1=CW_BGROUP(wLeftBaseSub1, $
- radioOptions, SET_VALUE=1, $
- /ROW, /RETURN_INDEX, /EXCLUSIVE, $
- /NO_RELEASE, UVALUE='RADIO1')
-
- wLeftBaseSub2=WIDGET_BASE(wLeftBase, $
- /ALIGN_CENTER, /COLUMN, /FRAME)
-
- wSelect2=WIDGET_LABEL(wLeftBaseSub2, $
- VALUE='Display Over Oceans:')
-
- wGroup2=CW_BGROUP(wLeftBaseSub2, $
- radioOptions, SET_VALUE=0, $
- /ROW, /RETURN_INDEX, /EXCLUSIVE, $
- /NO_RELEASE, UVALUE='RADIO2')
-
- wLeftBaseSub3=WIDGET_BASE(wLeftBase, $
- /ALIGN_CENTER, /COLUMN, /FRAME)
-
- wslider3=WIDGET_SLIDER(wLeftBaseSub3, $
- /SUPPRESS, MINIMUM=nColors/2, $
- MAXIMUM=nColors-1, $
- VALUE=nColors/2, $
- EVENT_PRO='GlobeStretch_Event', $
- TITLE='Stretch temperature minimum')
-
- wslider4=WIDGET_SLIDER(wLeftBaseSub3, $
- /SUPPRESS, MINIMUM=nColors/2, $
- MAXIMUM=nColors-1, $
- VALUE=nColors-1, $
- EVENT_PRO='GlobeStretch_Event', $
- TITLE='Stretch temperature maximum')
-
- wLeftBaseSub4=WIDGET_BASE(wLeftBase, $
- /ALIGN_CENTER, /COLUMN, /FRAME)
-
- wslider1=WIDGET_SLIDER(wLeftBaseSub4, $
- /SUPPRESS, MINIMUM=0, $
- MAXIMUM=nColors/2-1, VALUE=0, $
- EVENT_PRO='GlobeStretch_Event', $
- TITLE='Stretch topography minimum ')
-
- wslider2=WIDGET_SLIDER(wLeftBaseSub4, $
- /SUPPRESS, MINIMUM=0, $
- MAXIMUM=nColors/2-1, VALUE=nColors/2-1, $
- EVENT_PRO='GlobeStretch_Event', $
- TITLE='Stretch topography maximum ')
-
- wRightBase=WIDGET_BASE(wSubBase, /ALIGN_CENTER, /COLUMN)
-
- wDraw=WIDGET_DRAW(wRightBase, XSIZE=screenSize[0]*.48, $
- YSIZE=ScreenSize[0]*.48, $ ;keep isotropic
- UVALUE='DRAW', /BUTTON_EVENTS, $
- GRAPHICS_LEVEL=2, RETAIN=0, /EXPOSE_EVENTS)
-
- wStatusBase=WIDGET_BASE(wTopBase, /ROW, MAP=0)
-
- nWidgets=2
- wText=LONARR(nWidgets)
- widTips, wStatusBase, sText.text, wText, NWIDGETS=nWidgets
-
- ; Realize the widget hierarchy.
- ;
- WIDGET_CONTROL, wTopBase, /REALIZE
- WIDGET_CONTROL, HOURGLASS=1
- WIDGET_CONTROL, wDraw, GET_VALUE=oWindow
-
- ; Set the user values of each slider to the ids of all sliders because
- ; these will be needed in the event handler to avoid cases whereby
- ; minimum sliders are set to values larger than maximum sliders and
- ; vice versa.
- ;
- wsliders=[wslider1, wslider2, wslider3, wslider4]
-
- ; Set the initial value of the sliders.
- ;
- WIDGET_CONTROL, wslider1, SET_UVALUE=wsliders
- WIDGET_CONTROL, wslider2, SET_UVALUE=wsliders
- WIDGET_CONTROL, wslider3, SET_UVALUE=wsliders
- WIDGET_CONTROL, wslider4, SET_UVALUE=wsliders
-
- ; Size and map the tips.
- ;
- sizeTips, wTopBase, wText, wStatusBase
- WIDGET_CONTROL, wStatusBase, MAP=1
-
- ; Create the objects.
- ; Make the continent-topo & ocean-temperature
- ; the default view.
- ;
- sObject=GlobeMakeObjects(reds, greens, blues, screenSize, $
- pImageTopoTemp, oWindow)
-
- ; Build sState structure used in event handlers.
- ;
- sState={$
- wGroup1:wGroup1, $ ; Widget Id radio buttons
- wGroup2:wGroup2, $ ; Widget Id radio buttons
- wDraw:wDraw, $ ; Widget draw ID
- oImage:sObject.oImage, $ ; Image object
- oSphere:sObject.oSphere, $ ; Sphere object
- oTrack:sObject.oTrack, $ ; Trackball object
- oModelTranslate:sObject.oModelTranslate, $ ; Models
- oModelRotate:sObject.oModelRotate, $
- oModelScale:sObject.oModelScale, $
- OContainer: sObject.oContainer, $ ; Container object
- oWindow:sObject.oWindow, $ ; Widnow object
- oView:sObject.oView, $ ; View object
- oFont:sObject.oFont, $ ; Font object
- oText:sObject.oText, $ ; Text object
- oPalette:sObject.oPalette, $ ; Color palette object
- resetTransform:sObject.resetTransform, $ ; Transformation matrix to reset
- pImageTemp:pImageTemp, $ ; Pointers to images
- pImageTopo:pImageTopo, $
- pImageTempTopo:pImageTempTopo, $
- pImageTopoTemp:pImageTopoTemp, $
- nColors:nColors, $ ; Number of available colors
- reds:reds, $ ; RGB color arrays
- greens:greens, $
- blues:blues, $
- colorTable:colorTable, $ ; Color table to restore
- fileNameAbout:fileNameAbout, $
- groupBase: groupBase $ ; Base of Group Leader
- }
-
- WIDGET_CONTROL, wTopBase, SET_UVALUE=sState, /NO_COPY
-
- WIDGET_CONTROL, HOURGLASS=0
-
- ; Remove the starting up text.
- ;
- sObject.oModelTranslate->Remove, sObject.oText
-
- ; Returns the top level base to the APPTLB keyword.
- ;
- appTLB=wTopBase
-
- ; Modify the initial setting of the sliders. First create
- ; a pseudo event structure, then call the globeStretch_Event
- ; routine with the pseudo structure, then set the slider
- ; to the desired value
- ;
- ; Stretching the temperature minimum slider at 30% of
- ; its range and rotate the globe.
- ;
- sObject.oModelRotate->Rotate, [0, 1, 0], -20.0
- sObject.oModelRotate->Rotate, [1, 0, 0], 10.0
- deltaTempMin = (nColors-1 - nColors/2 ) * 0.3
- increment = (deltaTempMin) / 2
- for i = 0, deltaTempMin, increment do begin
- sObject.oModelRotate->Rotate, [0, 1, 0], -5
- sObject.oModelRotate->Rotate, [1, 0, 0], 2.5
- newValue = nColors/2 + i
- pseudoEvent = { $
- ID : wslider3, $
- TOP: wTopBase, $
- HANDLER: wslider3, $
- VALUE: newValue, $
- DRAG: 0 $
- }
- WIDGET_CONTROL, wslider3, SET_VALUE=newValue
- globeStretch_Event, pseudoEvent
- endfor
-
- ; Stretching the temperature maximum slider at 85% of
- ; its range and rotate the globe.
- ;
- deltaTempMax = (nColors-1 - nColors/2)*0.15
-
- increment = (deltaTempMax) / 3
- for i = 0, deltaTempMax, increment do begin
- sObject.oModelRotate->Rotate, [0, 1, 0], -5
- sObject.oModelRotate->Rotate, [1, 0, 0], 2.5
- newValue = (nColors-1) - i
- pseudoEvent = { $
- ID : wslider4, $
- TOP: wTopBase, $
- HANDLER: wslider4, $
- VALUE: newValue, $
- DRAG: 0 $
- }
- WIDGET_CONTROL, wslider4, SET_VALUE=newValue
- globeStretch_Event, pseudoEvent
- endfor
-
- ; Stretching the topography maximum slider at 35% of
- ; its range.
- ;
- deltaTempMax = nColors/2 - 1
- newValue = (nColors/2 - 1) * 0.35
- pseudoEvent = { $
- ID : wslider2, $
- TOP: wTopBase, $
- HANDLER: wslider2, $
- VALUE: newValue, $
- DRAG: 0 $
- }
- WIDGET_CONTROL, wslider2, SET_VALUE=newValue
- globeStretch_Event, pseudoEvent
-
- ; Register with the XMANAGER
- ;
- XMANAGER, 'd_Globe', wTopBase, /NO_BLOCK, $
- EVENT_HANDLER='d_Globe_Event', CLEANUP="d_GlobeCleanup"
-
- end
-
-